package com.jic.filecenter.controller.errors;

import com.jic.common.base.vo.RestResult;
import com.jic.common.base.vo.errors.ErrorConstants;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.springframework.dao.ConcurrencyFailureException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.NativeWebRequest;
import org.zalando.problem.Problem;
import org.zalando.problem.Status;
import org.zalando.problem.spring.web.advice.ProblemHandling;

import java.util.Arrays;
import java.util.NoSuchElementException;

/**
 * Controller advice to translate the server side exceptions to client-friendly json structures.
 * The error response follows RFC7807 - Problem Details for HTTP APIs (https://tools.ietf.org/html/rfc7807)
 */
@ControllerAdvice
@Slf4j
public class ExceptionTranslator implements ProblemHandling {

    private static final String MESSAGE_KEY = "msg";

    @ExceptionHandler
    public ResponseEntity<Problem> handleNoSuchElementException(NoSuchElementException ex, NativeWebRequest request) {
        Problem problem = Problem.builder()
            .withStatus(Status.NOT_FOUND)
            .with(MESSAGE_KEY, ErrorConstants.ENTITY_NOT_FOUND_TYPE)
            .build();
        return create(ex, problem, request);
    }

    @ExceptionHandler
    public ResponseEntity<Problem> handleConcurrencyFailure(ConcurrencyFailureException ex, NativeWebRequest request) {
        Problem problem = Problem.builder()
            .withStatus(Status.CONFLICT)
            .with(MESSAGE_KEY, ErrorConstants.ERR_CONCURRENCY_FAILURE)
            .build();
        return create(ex, problem, request);
    }


    @ExceptionHandler(FileCenterException.class)
    @ResponseBody
    public RestResult handleDeviceCenterException(FileCenterException ex) {
        return RestResult.error(ex.getStatus(), ex.getMessage());
    }


    @Override
    public ResponseEntity handleThrowable(Throwable ex, NativeWebRequest x){
        log.error("AOP Filter Exception",ex);
        RestResult restResult = new RestResult();
        restResult.setCode(FileCenterErrorCode.UNKNOWN);
        restResult.setMsg("系统异常请联系管理员");
        ResponseEntity<RestResult> entity = new ResponseEntity<RestResult>(restResult, HttpStatus.INTERNAL_SERVER_ERROR);
        return entity;
    }
}
